<template>
  <div v-show="loading && !error" style="text-align: center; margin-top: 10rem">
    <Loading size="72px" color="#0094ff">加载中...</Loading>
  </div>
  <div v-show="error" style="text-align: center; margin-top: 10rem; font-size: 60px">
    Error: {{ error }}
  </div>
  <div class="pay-container" v-show="!loading && !error">
    <main v-if="trueInput">
      <div class="mark-top" :style="{ backgroundColor: payInfo.theme }"></div>
      <div class="page-title">
        <Icon :name="payInfo?.ico" size="32px" />
        {{ payInfo?.pageTitle }}
      </div>
      <div class="container">
        <InfoCard>
          <template #header>
            <div class="header-tpl">
              <Icon name="gold-coin" />
              <div style="margin: 0 8px">{{ payInfo.payMessage.amount }}</div>
              <Button @click="onCopy(payInfo?.payMessage.amount)" style="margin-left: 8px" type="primary" size="small"
                icon="description">复制</Button>
            </div>
          </template>
          <template #content>
            <div class="content-tpl">
              <div style="
                  display: flex;
                  justify-content: center;
                  align-items: center;
                  margin-bottom: 8px;
                  font-size: 14px;
                ">
                订单编号: {{ payInfo.orderNo
                }}<Button style="margin-left: 8px" size="small" icon="description"
                  @click="onCopy(payInfo?.orderNo)"></Button>
              </div>
              <div class="flex">
                截止付款倒计时: <CountDown :time="payInfo.payMessage.time"></CountDown>
              </div>
            </div>
          </template>
        </InfoCard>

        <template v-for="(item, index) in sortKey" :key="index">
          <component v-if="comps[item]" :payInfo="payInfo" :is="comps[item]"></component>
        </template>
      </div>
    </main>

    <Popup v-model:show="pop.show" style="width: 400px" round :before-close="onClose">
      <VanForm validate-trigger="onSubmit" @submit="submitInput" ref="popForm">
        <InfoCard>
          <template #header>
            <div class="text-center" v-html="pop.title"></div>
          </template>
          <template #content>
            <div class="text-center" v-html="pop.describe"></div>

            <CellGroup>
              <Field :placeholder="pop.input" name="name" :rules="generateRules(pop.checkbox)" v-model="pop.value"
                :border="true" style="border:1px solid #e4e4e4;border-radius: 6px;">
              </Field>
            </CellGroup>
          </template>
          <template #footer>
            <div class="ma-4 text-right">
              <Button native-type="submit" type="primary" size="small">提交</Button>
            </div>
          </template>
        </InfoCard>
      </VanForm>
    </Popup>

    <!-- 顺序弹窗 -->
    <Popup v-model:show="popCustom.show" style="width: 400px" round :before-close="onPopClose">
      <InfoCard>
        <template #header>
          <div class="text-center" v-html="popCustom.info.title"></div>
        </template>
        <template #content>
          <div class="text-center" v-html="popCustom.info.content"></div>
        </template>
        <template #footer>
          <div class="ma-4 text-right">
            <Button @click="nextModal" type="primary" size="small">{{
              popCustom.info.okText
              }}</Button>
          </div>
        </template>
      </InfoCard>
    </Popup>
    <!-- 顺序弹窗 -->

    <Popup style="min-width: 400px" v-model:show="payStatusModal.success" round>
      <InfoCard>
        <template #header>
          <div class="text-center" v-html="payInfo.paySuccessTitle"></div>
        </template>
        <template #content>
          <div class="text-center" v-html="payInfo.paySuccessContext"></div>
        </template>
      </InfoCard>
    </Popup>

    <Popup style="min-width: 400px" v-model:show="payStatusModal.out" round>
      <InfoCard>
        <template #header>
          <div class="text-center" v-html="payInfo.payOutTitle"></div>
        </template>
        <template #content>
          <div class="text-center" v-html="payInfo.payOutContext"></div>
        </template>
        <template #footer>
          <div class="ma-4 text-right">
            <Button :url="navigatorUrl" type="primary" size="small">{{
              payInfo.payOutButton
              }}</Button>
          </div>
        </template>
      </InfoCard>
    </Popup>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { Icon, Button, Popup, Loading, showNotify, Field, CellGroup, Form as VanForm } from 'vant'
import InfoCard from '@/components/InfoCard.vue'
import CountDown from '@/components/CountDown.vue'

import { useRoute } from 'vue-router'
import request from '@/utils/request'
import QrCode from '@/components/qrCode.vue'
import Type from '@/components/type.vue'
import UpImg from '@/components/upImg.vue'
import Verify from '@/components/verify.vue'
import Video from '@/components/video.vue'
import Captcha from '@/components/Captcha.vue'
import Characters from '@/components/characters.vue'
import ButtonA from '@/components/ButtonA.vue'

const comps = {
  button: ButtonA,
  qrcode: QrCode,
  type: Type,
  upImg: UpImg,
  verify: Verify,
  video: Video,
  captcha: Captcha,
  characters: Characters
}

const RULES = ref({
  '0': { pattern: /\d/, message: '数字' },
  '1': { pattern: /[A-Za-z]/, message: '英文' },
  '2': { pattern: /[\u4e00-\u9fa5]/, message: '中文' }
})

const generateRules = (checkboxValue) => {
  if (typeof checkboxValue === 'string') {
    checkboxValue = checkboxValue.split(',').map(Number)
  }

  // 如果是空数组，返回空规则，允许任何输入
  if (Array.isArray(checkboxValue) && checkboxValue.length === 0) {
    return []
  }

  if (Array.isArray(checkboxValue) && checkboxValue.length > 0) {
    const patterns = checkboxValue.map(key => RULES.value[key]?.pattern).filter(Boolean)
    const messages = checkboxValue.map(key => RULES.value[key]?.message).filter(Boolean)

    return [
      {
        validator: (value) => {
          const combinedPattern = new RegExp(`^[${patterns.map(p => p.source).join('')}]+$`)
          if (!combinedPattern.test(value)) {
            return new Error(`请输入${messages.join('、')}`)
          }
        }
      }
    ]
  }

  return []
}

const payInfo = ref({
  buttonTop: '0',
  ico: '',
  icoTitle: '',
  item: {},
  orderNo: '',
  pageTitle: '',
  payMessage: {
    agentImgSrc:
      'https://cdn.zwswbm.com/storage/default/20240415/fineslinkerddf62bcde0026452daca3041fccf1b18f20a29c4.png',
    agentImgTitle: '',
    amount: '200.00',
    input: [],
    time: 890
  },
  payOutButton: '',
  payOutContext: '',
  payOutTitle: '',
  paySuccessContext: '',
  paySuccessTitle: '',
  theme: '#cb2a2a',
  input: false
})
const payStatusModal = ref({
  success: false,
  out: false
})
const pop = ref({
  show: false,
  title: '',
  describe: '',
  input: '',
  checkbox: 0,
  value: '',
  status: false
})
const popCustom = ref({
  show: false,
  index: 0,
  modals: [],
  info: {}
})

const loading = ref(true)
const orderNo = ref<string | null>(null)
const route = useRoute()
const error = ref(null)
const popForm = ref(null)
const navigatorUrl = ref('')
const sortKey = ref([])
const trueInput = ref(false)

// 顺序弹窗
function initModal(modalInfo: any) {
  const isShowData = localStorage.getItem(orderNo.value)
  if (isShowData === '1') return

  popCustom.value = {
    show: true,
    index: 0,
    modals: [],
    info: modalInfo[0]
  }
  popCustom.value.modals = modalInfo.sort(function (a, b) {
    return a.sort > b.sort
  })
}
function nextModal() {
  if (popCustom.value.index < popCustom.value.modals.length - 1) {
    popCustom.value.index++
    popCustom.value.info = popCustom.value.modals[popCustom.value.index]
  } else {
    popCustom.value.show = false
    localStorage.setItem(orderNo.value, '1')
  }
}
// 顺序弹窗

function onCopy(content: string | number) {
  navigator.clipboard
    .writeText(String(content))
    .then(() => {
      // 复制成功
      showNotify({ type: 'success', message: '复制成功' })
    })
    .catch(() => {
      // 复制失败
      showNotify({ type: 'danger', message: '复制失败' })
    })
}

function clearHtml(val: string) {
  return val.replace(/<[^<>]*>/g, '')
}

function onClose() {
  return pop.value.status
}

function onPopClose() {
  return false
}

function submitInput(values) {
  return request
    .post('/api/orderCheckIn/orderMember', {
      orderNo: orderNo.value,
      input: values.name
    })
    .then((res) => {
      if (res.data.code === 1) {
        pop.value.status = true
        pop.value.show = false
        window.location.reload()
      } else {
        showNotify({ type: 'danger', message: res.data.msg })
      }
    })
}

function refreshOrderStatus() {
  setTimeout(() => {
    request
      .post('/api/orderCheckIn/orderStatus', {
        orderNo: orderNo.value
      })
      .then((res) => {
        if (res.data.code === 30001) {
          refreshOrderStatus()
        } else if (res.data.code === 1) {
          payStatusModal.value.success = true
          setTimeout(() => {
            window.location.reload()
          }, 3000)
        } else if (res.data.code === 30002) {
          payStatusModal.value.out = true
          window.location.reload()
        } else {
          showNotify({ type: 'danger', message: res.data.msg })
        }
      })
  }, 1000)
}

onMounted(async () => {
  orderNo.value = route.params.orderNo
  request
    .post('/api/orderCheckIn/orderPay', {
      orderNo: orderNo.value
    })
    .then((res) => {
      if (res.data.code === 30007) {
        const data = res.data.data
        payInfo.value = {}
        setTimeout(() => {
          loading.value = false
          if (data.input === false) {
            pop.value = {
              show: true,
              title: data.popTitle,
              describe: data.popDescribe,
              input: clearHtml(data.popInput),
              checkbox: data.popCheckbox,
              value: '',
              status: false
            }
          }
        }, 500)
        return
      }
      if (res.data.code !== 1) {
        alert(res.data.msg)
        error.value = res.data.msg
        return
      }
      if (res.data.code == 1 && res.data.msg == '支付成功') {
        error.value = res.data.msg
        return
      }
      payInfo.value = res.data.data
      // 组件排序
      sortKey.value = Object.keys(payInfo.value.item).sort(function (a, b) {
        return payInfo.value.item[a].sort - payInfo.value.item[b].sort
      })

      if (res.data.data.item?.popCustom?.characters)
        initModal(res.data.data.item?.popCustom?.characters)
      refreshOrderStatus()
      setTimeout(() => {
        loading.value = false
        trueInput.value = true
        document.title = payInfo.value.orderNo + ' - ' + payInfo.value.pageTitle
        if (payInfo.value.item?.pop && payInfo.value.input === false) {
          pop.value = {
            show: true,
            title: payInfo.value.item?.pop.popTitle,
            describe: payInfo.value.item?.pop.popDescribe,
            input: clearHtml(payInfo.value.item?.pop.popInput),
            checkbox: payInfo.value.item?.pop.popCheckbox,
            value: '',
            status: false
          }
        }
      }, 500)
    })
})
</script>

<style scoped lang="less">
:deep(img) {
  width: 100% !important;
  object-fit: cover !important;
}

@media screen and (min-width: 800px) {
  main {
    max-width: 400px;
  }

  .pay-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 100%;
  }
}

.mark-top {
  width: 100%;
  height: 120px;
  background-color: #fff;
  position: fixed;
  top: 0;
  left: 0;
  z-index: -1;
  border-bottom-left-radius: 4px;
  border-bottom-right-radius: 4px;
}

.page-title {
  text-align: center;
  font-size: 20px;
  color: #fff;
  font-weight: bold;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  margin-top: 30px;
}

.container {
  margin-top: 8px;
  padding: 8px;

  .header-tpl {
    display: flex;
    justify-content: center;
    align-items: center;
    color: #f50;
    font-weight: bold;
    font-size: 30px;
  }

  .content-tpl {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    font-weight: bold;

    >div::before {
      content: ' * ';
      color: #f50;
    }
  }
}
</style>
